package com.example.goband.api;

import com.example.goband.common.AppVariable;
import com.example.goband.game.MatchRequest;
import com.example.goband.game.MatchResponse;
import com.example.goband.game.Matcher;
import com.example.goband.game.OnlineUserManager;
import com.example.goband.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 22479
 * Date: 2023-06-02
 * Time: 11:36
 */
@Component
public class MatchAPI extends TextWebSocketHandler {

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private OnlineUserManager onlineUserManager;

    @Resource
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //玩家上线,加入到OnlineUserManager中 |   上线逻辑

        //1、获取到当前用户的身份信息（谁在游戏大厅，建立的连接）
        /**
         * session.getAttributes() 返回的是一个Map
         * 这里的Map来源是依靠我们在配置WebSocketConfig时候加上的:
         * .addInterceptors(new HttpSessionHandshakeInterceptor())这个操作
         * 这个逻辑就把HttpSession中的Attributes都给拿到    WebSocketSession中了
         *  在Http 登录的逻辑中,我们往HttpSession中存储了user数据: session.setAttribute(AppVariable.USER_SESSION_KEY,user);
         *  此时就可以在WebSocketSession中把之前的HttpSession存储的user对象拿到
         *
         */
        User user = (User)session.getAttributes().get(AppVariable.USER_SESSION_KEY);

        /**
         * 判定多设备登录模块
         */
        //2、判断当前用户是否已经在线，如果已经在线停止后续逻辑
        WebSocketSession socketSession = onlineUserManager.getFromGameHall(user.getUserId());
        if(socketSession != null) {
            //已在其他设备登录
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("当前用户已在其他设备登录!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            //断开连接 禁止多开
            session.close();
            return;
        }



        //3、拿到了身份信息，就可以把玩家设置成在线状态
        onlineUserManager.enterGameHall(user.getUserId(), session);

        System.out.println("玩家：" + user.getUsername() + "  进入了游戏大厅");


    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        User user = (User) session.getAttributes().get(AppVariable.USER_SESSION_KEY);

        //获取客户端发给服务器的数据
        String payload = message.getPayload();
        //当前这个数据载荷是JSON格式的字符串,就需要把它转换成JAVA对象 - MathRequest
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse response = new MatchResponse();

        if(request.getMessage().equals("startMatch")) {
            //进入匹配队列
            //todo...
            matcher.add(user);
            response.setOk(true);
            response.setMessage("startMatch");
        } else if(request.getMessage().equals("stopMatch")) {
            //离开匹配队列
            matcher.remove(user);
            response.setOk(true);
            response.setMessage("stopMatch");
        } else {
            response.setOk(false);
            response.setReason("非法的请求匹配");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));


    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User)session.getAttributes().get(AppVariable.USER_SESSION_KEY);

        //判断退出的是多设备登录用户还是正常用户
        WebSocketSession socketSession = onlineUserManager.getFromGameHall(user.getUserId());
        if(socketSession == session) {
            //判断当前session和 存储在用户管理器的session是否一致
            onlineUserManager.exitGameHall(user.getUserId());
            System.out.println("玩家：" + user.getUsername() + "  离开游戏大厅");
            //如果玩家正在匹配中,异常断开连接,则要异常匹配
            matcher.remove(user);
        }

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        //玩家下线，从Online里删除
        User user = (User)session.getAttributes().get(AppVariable.USER_SESSION_KEY);

        //判断退出的是多设备登录用户还是正常用户
        WebSocketSession socketSession = onlineUserManager.getFromGameHall(user.getUserId());
        if(socketSession == session) {
            //判断当前session和 存储在用户管理器的session是否一致
            onlineUserManager.exitGameHall(user.getUserId());
            System.out.println("玩家：" + user.getUsername() + "  离开游戏大厅");
            //如果玩家正在匹配中,异常断开连接,则要异常匹配
            matcher.remove(user);
        }

    }
}
